/**
 *  Copyright (C) 2008-2013  Telosys project org. ( http://www.telosys.org/ )
 *
 *  Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *          http://www.gnu.org/licenses/lgpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.telosys.util;

import java.lang.reflect.Field;

/**
 * Utility class for JAVA CLASS operations ( set of static methods )
 * 
 * @author Laurent GUERIN
 * 
 */
public final class ClassUtil
{
    /**
     * No constructor for this class !
     */
    private ClassUtil()
    {
    }

    //-----------------------------------------------------------------------------------
    /**
     * Return the value of a static field for a given class.
     * @param cl : the class
     * @param sFieldName : the field name to find in the class
     * @return the field value
     * @throws Exception
     */
    public static Object getFieldValue ( Class<?> cl, String sFieldName )  throws Exception
    {
    	if ( null == cl ) {
    		throw new IllegalArgumentException("Class is null");
    	}
    	if ( null == sFieldName ) {
    		throw new IllegalArgumentException("Field name is null");
    	}

    	String sErrMsg = "getFieldValue(" + cl.getName() + ", " + sFieldName + ") : ";
        try
        {
            Field field = cl.getDeclaredField(sFieldName);
            return field.get(null) ;
        } catch (SecurityException e)
        {
            throw new Exception( sErrMsg+e.getMessage(), e );
        } catch (NoSuchFieldException e)
        {
            throw new Exception( sErrMsg+e.getMessage(), e );
        } catch (IllegalArgumentException e)
        {
            throw new Exception( sErrMsg+e.getMessage(), e );
        } catch (IllegalAccessException e)
        {
            throw new Exception( sErrMsg+e.getMessage(), e );
        }
        //return null ;        
    }
    
    //-----------------------------------------------------------------------------------
    /**
     * Returns the "simple name" of the given class <br>
     * Just the same as Class.getSimpleName() in Java 5+<br>
     * e.g. returns "String" for "java.lang.String" class
     * @param cl
     * @return the simple name
     */
    public static String getSimpleName(Class<?> cl)
    {
    	if ( null == cl ) {
    		throw new IllegalArgumentException("Class is null");
    	}
    	return getSimpleName( cl.getName() ) ;
    }

    //-----------------------------------------------------------------------------------
    /**
     * Returns the "simple name" of the given class name <br>
     * Just the same as Class.getSimpleName() in Java 5+<br>
     * e.g. returns "String" for "java.lang.String"
     * @param sClassName the name of the class
     * @return  the simple name
     */
    public static String getSimpleName(String sClassName)
    {
    	if ( null == sClassName ) {
    		throw new IllegalArgumentException("Class name is null");
    	}
    	
        int i = sClassName.lastIndexOf('.');
        if ( i >= 0 )
        {
            return sClassName.substring(i+1);
        }
        else
        {
            return sClassName;
        }
    }
    
	/**
     * Returns the "package name" of the given class name <br>
     * e.g. returns "java.lang" for "java.lang.String"
	 * @param sFullClassName
	 * @return the package name
	 */
	public static String getPackageName(String sFullClassName) 
	{
    	if ( null == sFullClassName ) {
    		throw new IllegalArgumentException("Class name is null");
    	}
    	
		String s = sFullClassName.trim();
		int i = s.lastIndexOf('.');
		if ( i >= 0 )
		{
			return s.substring(0,i);
		}
		return "" ;
	}
	
    //------------------------------------------------------------------------------------
	/**
	 * Try to load the Java class for the given class name without ClassNotFoundException
	 * @param fullClassName
	 * @return the class loaded or null if not found 
	 */
	public static Class<?> tryToLoadClass(String fullClassName)
    {
    	if ( null == fullClassName ) {
    		throw new IllegalArgumentException("Class name is null");
    	}
    	
        // trace("tryToLoadClass('" + sServiceClassName + "')");
	    Class<?> c = null ;
        try
        {
            c = Class.forName(fullClassName); 
        } catch (ClassNotFoundException e)
        {
            c = null ;	        
        }
        return c ;        
    }
	
    //---------------------------------------------------------------------------
    /**
     * Creates an instance of the given class using the default constructor
     * 
     * @param clazz
     * @return the instance created or null if an error occurs (cannot load class or cannot instantiate)
     */
    public static Object createObjectInstance(Class<?> clazz)
    {
    	if ( null == clazz ) {
    		throw new IllegalArgumentException("Class is null");
    	}
        try
        {
            Object theInstance = clazz.newInstance();
            return theInstance;
        } catch (Throwable t)
        {
            return null;
        }
    }

    //---------------------------------------------------------------------------
    public static Object createObjectInstance(String fullClassName)
    {
    	if ( null == fullClassName ) {
    		throw new IllegalArgumentException("Class name is null");
    	}
    	Class<?> clazz = tryToLoadClass(fullClassName) ;
    	if ( clazz != null ) {
    		Object instance = createObjectInstance(clazz);
    		if ( instance != null ) {
    			return instance ;
    		}
    		else {
        		throw new RuntimeException("Cannot create instance of class '" + fullClassName + "'");
    		}
    	}
    	else {
    		throw new RuntimeException("Cannot load class '" + fullClassName + "'");
    	}
    }
    
}